import EventMap from "../utils/EventMap";
import IRefrence from "../utils/IRefrence";
import IEvent from "../utils/Chat/Contract/IEvent";

/**
 *  聊天使用的websocket
 */
class ChatWebSocket {

    private  socket :WebSocket;

    private static chatWebSocket: ChatWebSocket;

    connectioned: boolean = false;

    url : string = 'ws://127.0.0.1:18308/chat';

    private constructor (url? :string) {

        if (url) {
            this.url = url;
        }

        this.socket = new WebSocket(this.url);
    }

     public static init(url? :string): void {
        console.log("初始化开始了");
        if (! (ChatWebSocket.chatWebSocket instanceof ChatWebSocket)) {
            ChatWebSocket.chatWebSocket = new ChatWebSocket(url);
        }
        console.log("初始化完成了");

        this.chatWebSocket.connectWebScoket();
    }

    /**
     * 获取类的实例
     * @param url 
     */
    public static getInstance(): ChatWebSocket {

        if (! (ChatWebSocket.chatWebSocket instanceof ChatWebSocket)) {
            throw "聊天websocket未被初始化";
        }
    

        return   ChatWebSocket.chatWebSocket ;
    }

    close(code?: number, reason?: string) :void {
        this.socket.close(code, reason);
    }

    async connectWebScoket() {

        this.socket.onopen = (event: Event) => {
            console.log(event);

            this.sendContent({
                cmd: "server.initChat"
            });
        };

        this.socket.onmessage = (event: MessageEvent) => {

            if (!event.data || event.data.data) {
                return;
            }
            let data = JSON.parse(event.data);
            console.log(data);
            let cmd = data?.cmd;

            if (!cmd) {
                return;
            }

            let callBack = EventMap.getCallBack(cmd);

            if (!callBack) {
                return;
            }

            let content = this.getCallBackObject(callBack).handle(data);

            console.log(content);

            if (!content) {
                return;
            }

            document.getElementById("u-16")?.insertAdjacentHTML('beforeend', content);
        }


        this.socket.onerror = (ev: Event) => {
            console.log(ev);
        }

    }
    /**
        * name
        */
    public getCallBackObject(obj: IRefrence): IEvent {
        return new obj();
    }

    sendContent = (data: {}, callback?: Function) => {
        this.waitForConnection(() => {
            this.socket.send(JSON.stringify(data));
            if (typeof callback !== 'undefined') {
                callback();
            }
        }, 1000);
    }

    waitForConnection = (callback: Function, interval: number = 1) => {
        if (this.socket.readyState === 1) {
            callback();
        } else {
            // optional: implement backoff for interval here
            setTimeout(() => {
                this.waitForConnection(callback, interval);
            }, interval);
        }
    };
}

export default ChatWebSocket;
